package main

import (
	"context"
	"encoding/binary"
	"fmt"
	"github.com/zing-dev/general-protocol-lib/log"
	dts_tcp "github.com/zing-dev/general-protocol-lib/source/dts-tcp-client"
	"github.com/zing-dev/go-bit-bytes/bit"
	"net"
	"net/http"
	"os"
	"os/signal"
	"time"
)

func Server() {
	client := dts_tcp.NewClient(context.Background(), &dts_tcp.Config{
		Id:             1,
		Name:           "空军一号",
		Server:         "10.0.0.20:8090",
		Debug:          true,
		ChannelMapping: map[byte]int{1: 110, 2: 300, 3: 343},
		FilterSignal:   true,
		Reconnect:      false,
	})
	client.CallConnectChange("CallConnect", func(status dts_tcp.Status) {
		log.L.Info(fmt.Sprintf("连接状态: %s", &status))
	})
	client.CallMessage("CallMessage", func(message dts_tcp.Message) {
		log.L.Info(fmt.Sprintf("%s %s: %s", message.At.Format("2006-01-02 15:04:05"), message.Level, message.Message))
	})
	client.CallChannelTemperature("CallChannelTemperature", func(data dts_tcp.ChannelTemperature) {
		if data.Flag == dts_tcp.FlagTemperature {
			//log.L.Info(fmt.Sprintf("温度 通道id%d 总通道%d 通道号%d 数据标值%d %.2f %.2f %d", data.ChannelId, data.ChannelCount, data.ChannelNumber, data.Flag, data.Start, data.End,
			//	len(data.Temperatures)))
			//log.L.Info(data.Temperatures)
		}
	})
	client.CallTemperatureAlarm("CallTemperatureAlarm", func(alarms dts_tcp.TemperatureAlarm) {
		switch alarms.Type {
		case dts_tcp.ConstantTemperature:
			log.L.Info(fmt.Sprintf("定温 设备号%d 通道号%d 报警数量%d %s", alarms.Info.DeviceNumber, alarms.ChannelNumber, len(alarms.Alarms), alarms.AlarmsString()))
		case dts_tcp.DifferentialTemperature:
			log.L.Info(fmt.Sprintf("差温 设备号%d 通道号%d 报警数量%d %s", alarms.Info.DeviceNumber, alarms.ChannelNumber, len(alarms.Alarms), alarms.AlarmsString()))
		}
	})

	var (
		conn      net.Conn
		err       error
		connected bool
	)
	http.HandleFunc("/1", func(writer http.ResponseWriter, request *http.Request) {
		if connected {
			conn.Close()
			writer.Write([]byte("close"))
			connected = false
			return
		}
		conn, err = net.DialTimeout("tcp", "10.0.0.20:8090", time.Second*3)
		if err != nil {
			writer.Write([]byte(err.Error()))
			return
		}
		connected = true
		writer.Write([]byte("run"))
	})

	http.HandleFunc("/2", func(writer http.ResponseWriter, request *http.Request) {
		if client.GetStatus() == dts_tcp.Connecting {
			writer.Write([]byte("connecting"))
			return
		}
		if client.IsConnected() {
			client.Close()
			writer.Write([]byte("start close"))
			return
		}
		client.Run()
		writer.Write([]byte("run"))

	})

	var (
		start  = true
		ctx    context.Context
		cancel context.CancelFunc
	)
	http.HandleFunc("/3", func(writer http.ResponseWriter, request *http.Request) {
		if start {
			ctx, cancel = context.WithCancel(context.Background())
			go func() {
				for {
					select {
					case <-ctx.Done():
						fmt.Println("over")
						return
					case <-time.Tick(time.Second * 2):
						log.L.Info("do2...")
					case <-time.Tick(time.Second / 1000):
						log.L.Info("do1...")
						//default:
						//	time.Sleep(time.Second * 2)
						//	fmt.Println("default...")
					}
				}
			}()
			time.AfterFunc(time.Second*30, cancel)
			start = false
		} else {
			cancel()
			start = true
		}
	})
	http.HandleFunc("/4", func(writer http.ResponseWriter, request *http.Request) {
		if client.IsConnected() {
			client.TestStop()
			writer.Write([]byte("close"))
			return
		}
		client.TestRun()
		writer.Write([]byte("run"))
	})
	http.HandleFunc("/status", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte(fmt.Sprintf("%v,%v", client.GetStatus(), client.IsConnected())))
	})
	http.HandleFunc("/run", func(writer http.ResponseWriter, request *http.Request) {
		if client.GetStatus() == dts_tcp.Connecting {
			writer.Write([]byte("connecting"))
			return
		}
		if client.IsConnected() {
			writer.Write([]byte("already run"))
			return
		}
		go client.Run()
		writer.Write([]byte("start run..."))
	})
	http.HandleFunc("/stop", func(writer http.ResponseWriter, request *http.Request) {
		if !client.IsConnected() && !(client.GetStatus() == dts_tcp.Connecting) {
			writer.Write([]byte("already close"))
			return
		}
		client.Close()
		writer.Write([]byte("start close..."))
	})
	err = http.ListenAndServe(":1123", nil)
	if err != nil {
		log.L.Fatalln(err)
	}
}

func test() {
	Server()
	//time.AfterFunc(time.Minute, func() {
	//	client.Close()
	//})
	// if we're not ready to receive when the signal is sent.
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)

	// Block until a signal is received.
	s := <-c
	fmt.Println("Got ctrl+C:", s)
}

func test2() {
	conn, err := net.DialTimeout("tcp", "10.0.0.220:5000", time.Second*3)
	if err != nil {
		log.L.Fatal(err)
	}
	_, err = conn.Write([]byte("[Q]?CM#"))
	if err != nil {
		log.L.Error("write: ", err)
	}
	var data = make([]byte, 100)
	n, err := conn.Read(data)
	if err != nil {
		log.L.Info(err)
	}
	bit.DefaultEndPont = binary.LittleEndian
	log.L.Info(fmt.Sprintf("%x", data[:n]))
	log.L.Info(fmt.Sprintf("设备id: %d", data[8]))
	log.L.Info(fmt.Sprintf("ip: %d.%d.%d.%d", data[15], data[16], data[17], data[18]))
	log.L.Info(fmt.Sprintf("端口: %d", bit.ToUint16(data[19:21])))
	log.L.Info(fmt.Sprintf("硬件id: %03d%03d%03d%03d", data[21], data[22], data[23], data[24]))
}

func test3() {
	conn, err := net.DialTimeout("tcp", "10.0.0.220:5000", time.Second*3)
	if err != nil {
		log.L.Fatal(err)
	}
	_, err = conn.Write([]byte("[Q]?ID#"))
	if err != nil {
		log.L.Error("write: ", err)
	}
	var data = make([]byte, 100)
	n, err := conn.Read(data)
	if err != nil {
		log.L.Info(err)
	}
	bit.DefaultEndPont = binary.LittleEndian
	log.L.Info(fmt.Sprintf("%x", data[:n]))
	log.L.Info(fmt.Sprintf("设备id: %d", data[8]))
	log.L.Info(fmt.Sprintf("设备硬件id: %d%02d%02d%02d%04d", (data[14]<<4)+((data[13]&0xF0)>>4), data[13]&0xF, data[12], (data[11]&0xF0)>>4, data[11]&0xF))
}

func main() {
	log.Init()
	test3()

}
